import Joi from 'joi';
import debugCheck from '@kuiper-helpers/debug-check';
import * as validation from '../../common/validation';
import joiOmit from '../helpers/joiOmit';
import findManyFilter from '../../common/validation/findManyFilter';

export const pagination = {
	tags: ['api', 'asset'],
	description: '资产变动监测任务列表-分页查看',
	auth: debugCheck('disable-open-api-auth')
		? false
		: {
				mode: 'required',
				access: {
					// 只允许使用 URL Token 访问
					entity: 'app',
				},
		  },

	validate: {
		payload: Joi.object({
			page: Joi.number().default(1).description('当前页'),
			perPage: Joi.number().default(10).description('每页条目数'),
			filter: findManyFilter.asset.$_terms.keys
				.reduce((obj, { key, schema }) => {
					if (key !== 'uid') return obj.append({ [key]: schema });
					return obj.append({ uid: Joi.string().allow(null) });
				}, Joi.object())
				.append({
					createTimeGTE: Joi.date().description('创建时间大于等于'),
					createTimeLTE: Joi.date().description('创建时间小于等于'),
					targetSearch: Joi.string(),
				}),
		}),
	},

	// response: {
	// 	schema: Joi.object({
	// 		data: Joi.object({
	// 			AssetPagination: Joi.object({
	// 				count: Joi.number().description('总条数'),
	// 				pageInfo: Joi.object({
	// 					currentPage: Joi.number().description('当前页数'),
	// 					perPage: Joi.number().description('每页条数'),
	// 					pageCount: Joi.number().description('总页数'),
	// 					itemCount: Joi.number().description('总条数'),
	// 					hasNextPage: Joi.boolean().description('是否有下一页'),
	// 					hasPreviousPage: Joi.boolean().description('是否有上一页'),
	// 				}),
	// 				items: Joi.array().items(
	// 					validation.assetWithId.append({
	// 						result: joiOmit(validation.taskWithId, {
	// 							required: true,
	// 						}).allow(null),
	// 						stats: Joi.object({
	// 							ipCount: Joi.number().allow(null),
	// 							portCount: Joi.number().allow(null),
	// 							subdomainCount: Joi.number().allow(null),
	// 							ipBindDomainCount: Joi.number().allow(null),
	// 						}).allow(null),
	// 						user: Joi.object({
	// 							username: Joi.string().description('用户名'),
	// 						}),
	// 					})
	// 				),
	// 			}),
	// 		}),
	// 	}).label('Response'),
	// },

	handler: {
		injectGraphql: {
			payloadBuilder(request) {
				const {
					payload: { page, perPage, filter },
				} = request;

				return JSON.stringify({
					variables: { page, perPage, filter },
					// #region query
					query: `
						query($page: Int = 1, $perPage: Int = 10, $filter: FilterFindManyAssetInput, $sort: SortFindManyAssetInput = _ID_DESC) {
							AssetPagination(page: $page, perPage: $perPage, filter: $filter, sort: $sort) {
								count
								pageInfo {
									currentPage
									perPage
									pageCount
									itemCount
									hasNextPage
									hasPreviousPage
								}
								items {
									_id
									jobId
									job {
										_id
										note
									}
									alertSettings {
										alertGroupIds
										notification {
											email
											sms
											wechat
										}
									}
									taskSettings {
										enable
										name
										sourceIp
										target
										collect
										alert
										interval
									}
									target
									targetType
									triggerType
									uid
									createTime
									updateTime
									nextExecDate
									securityStatus
									result {
										_id
										endTime
										securityStatus
										isSpecialTask
										triggerType
										result {
											warningCount
											warnings {
												id
												title
												description
												impact
												category
												affects
												level
												isResolved
												ignoredTime
											}
											computedStats
											stats {
												ipCount
												portCount
												subdomainCount
												ipBindDomainCount
											}
										}
									}
									user {
										username
									}
								}
							}
						}`,
					// #endregion
				});
			},
			onResponse(resp) {
				resp.data.AssetPagination.items.forEach(e => {
					e.stats = e.result?.result?.stats || {
						ipCount: 0,
						portCount: 0,
						subdomainCount: 0,
						ipBindDomainCount: 0,
					};
				});
				return resp;
			},
		},
	},
};

export const findMany = {
	tags: ['api', 'asset'],
	description: '资产变动监测任务列表',
	auth: debugCheck('disable-open-api-auth')
		? false
		: {
				mode: 'required',
				access: {
					// 只允许使用 URL Token 访问
					entity: 'app',
				},
		  },

	validate: {
		payload: Joi.object({
			filter: findManyFilter.asset,
		}),
	},

	response: {
		schema: Joi.object({
			data: Joi.object({
				AssetMany: Joi.array().items(validation.assetWithId),
			}),
		}).label('Response'),
	},

	handler: {
		injectGraphql: {
			payloadBuilder(request) {
				const {
					payload: { filter },
				} = request;
				request.log.debug({ filter }, '请求资产变动监测任务列表');

				return JSON.stringify({
					variables: { filter },
					// #region query
					query: `
						query($filter: FilterFindManyAssetInput) {
							AssetMany(filter: $filter, limit: 0) {
								_id
								jobId
								alertSettings {
									alertGroupIds
									notification {
										email
										sms
										wechat
									}
								}
								taskSettings {
									enable
									name
									sourceIp
									target
									collect
									alert
									interval
								}
								target
								targetType
								triggerType
								securityStatus
								uid
								createTime
								updateTime
								nextExecDate
							}
						}`,
					// #endregion
				});
			},
		},
	},
};

export const updateById = {
	tags: ['api', 'asset'],
	description: '更新资产变动监测任务',
	auth: debugCheck('disable-open-api-auth')
		? false
		: {
				mode: 'required',
				access: {
					// 只允许使用 URL Token 访问
					entity: 'app',
				},
		  },

	validate: {
		params: Joi.object({
			assetId: Joi.string(),
		}),
		payload: joiOmit(validation.asset),
		query: Joi.object({
			immediateExec: Joi.string().description('立即执行任务'),
			enableMonitor: Joi.string().description('任务监测开关'),
		}).unknown(),
	},

	response: {
		schema: Joi.object({
			data: Joi.object({
				AssetUpdateById: Joi.object({
					recordId: Joi.string().description('更新记录的ID'),
				}),
			}),
		}).label('Response'),
	},

	handler: {
		injectGraphql: {
			payloadBuilder(request) {
				const {
					payload,
					params: { assetId },
					query: { immediateExec, enableMonitor },
				} = request;

				return JSON.stringify({
					variables: {
						immediateExec: immediateExec !== undefined,
						enableMonitor: enableMonitor !== undefined,
						record: payload,
						filter: { _id: assetId },
					},
					// #region query
					query: `
						mutation($filter: FilterUpdateOneAssetInput!, $record: UpdateOneAssetInput!, $immediateExec: Boolean, $enableMonitor: Boolean) {
							AssetUpdateById: AssetUpdateOne(record: $record, filter: $filter, immediateExec: $immediateExec, enableMonitor: $enableMonitor) {
								recordId
							}
						}`,
					// #endregion
				});
			},
		},
	},
};

export const findById = {
	tags: ['api', 'asset'],
	description: '根据ID查询资产变动监测任务',
	auth: debugCheck('disable-open-api-auth')
		? false
		: {
				mode: 'required',
				access: {
					// 只允许使用 URL Token 访问
					entity: 'app',
				},
		  },

	validate: {
		params: Joi.object({
			assetId: Joi.string(),
		}),
	},

	response: {
		schema: Joi.object({
			data: Joi.object({
				AssetById: validation.assetWithId.append({
					result: joiOmit(validation.taskWithId, {
						required: true,
					}).allow(null),
				}),
			}),
		}).label('Response'),
	},

	handler: {
		injectGraphql: {
			payloadBuilder(request) {
				const {
					params: { assetId },
				} = request;

				return JSON.stringify({
					variables: { _id: assetId },
					// #region query
					query: `
						query($_id: MongoID!) {
							AssetById: AssetOne(filter: { _id: $_id }) {
								_id
								jobId
								alertSettings {
									alertGroupIds
									notification {
										email
										sms
										wechat
									}
								}
								taskSettings {
									enable
									name
									sourceIp
									target
									collect
									alert
									interval
								}
								target
								targetType
								triggerType
								uid
								createTime
								updateTime
								nextExecDate
								result {
									_id
									endTime
									target
									taskType
									securityStatus
									isSpecialTask
									triggerType
									result {
										warnings {
											id
											title
											level
										}
										addition
										ipPorts {
											ip
											hostname
											location
											ports {
												port
												service
												proto
												server
												version
											}
										}
										subDomains {
											host
											point
										}
										ipBindDomains {
											ip
											domains {
												domain
												title
											}
										}
									}
								}
							}
						}`,
					// #endregion
				});
			},
		},
	},
};

export const count = {
	tags: ['api', 'asset'],
	description: '资产变动监测任务数量统计',
	auth: debugCheck('disable-open-api-auth')
		? false
		: {
				mode: 'required',
				access: {
					// 只允许使用 URL Token 访问
					entity: 'app',
				},
		  },

	validate: {
		payload: Joi.object({
			filter: findManyFilter.asset,
		}),
	},

	response: {
		schema: Joi.object({
			data: Joi.object({
				AssetCount: Joi.number().description('数量'),
			}),
		}).label('Response'),
	},

	handler: {
		injectGraphql: {
			payloadBuilder(request) {
				const {
					payload: { filter },
				} = request;

				return JSON.stringify({
					variables: { filter },
					// #region query
					query: `
						query($filter: FilterCountAssetInput) {
							AssetCount(filter: $filter)
						}`,
					// #endregion
				});
			},
		},
	},
};

export const addManualAssetTask = {
	tags: ['api', 'asset'],
	description: '资产变动监测自定义任务',
	auth: debugCheck('disable-open-api-auth')
		? false
		: {
				mode: 'required',
				access: {
					// 只允许使用 URL Token 访问
					entity: 'app',
				},
		  },

	validate: {
		params: Joi.object({
			assetId: Joi.string(),
		}),
		payload: Joi.object({
			uid: Joi.string(),
			alert: Joi.object({
				subdomain: Joi.boolean().default(true),
				port: Joi.boolean().default(true),
			}).description('后期会去掉'),
			collect: Joi.object({
				subdomain: Joi.boolean().default(true),
				port: Joi.boolean().default(true),
			}).default({ subdomain: true, port: true }),
			needAlert: Joi.boolean().description('发送告警通知'),
		}),
	},

	response: {
		schema: Joi.object({
			data: Joi.object({
				addManualAssetTask: joiOmit(validation.taskWithId),
			}),
		}).label('Response'),
	},

	handler: {
		injectGraphql: {
			payloadBuilder(request) {
				const {
					params: { assetId },
					payload,
				} = request;

				if (payload.needAlert !== undefined) {
					payload.alert.enable = payload.needAlert;
					delete payload.needAlert;
				}

				return JSON.stringify({
					variables: { ...payload, targetId: assetId },
					// #region query
					query: `
						mutation($alert: JSON!, $collect: JSON!, $uid: MongoID!, $targetId: MongoID!) {
							addManualAssetTask(alert: $alert, collect: $collect, uid: $uid, targetId: $targetId)
						}`,
					// #endregion
				});
			},
		},
	},
};

export const addSubdomain = {
	tags: ['api', 'asset'],
	description: '资产变动添加自定义子域名',
	auth: debugCheck('disable-open-api-auth')
		? false
		: {
				mode: 'required',
				access: {
					// 只允许使用 URL Token 访问
					entity: 'app',
				},
		  },

	validate: {
		params: Joi.object({
			assetId: Joi.string(),
		}),
		payload: Joi.object({
			domain: Joi.string().description('域名'),
			ip: Joi.string().description('IP'),
			note: Joi.string().description('备注'),
		}),
	},

	response: {
		schema: Joi.object({
			data: Joi.object({
				assetAddSubdomain: validation.assetWithId,
			}),
		}).label('Response'),
	},

	handler: {
		injectGraphql: {
			payloadBuilder(request) {
				const {
					params: { assetId },
					payload,
				} = request;

				return JSON.stringify({
					variables: { ...payload, assetId },
					// #region query
					query: `
						mutation($assetId: MongoID!, $domain: String!, $ip: String, $note: String ) {
							assetAddSubdomain(assetId: $assetId, domain: $domain, ip: $ip, note: $note) {
								_id
								alertSettings {
									alertGroupIds
									notification {
										email
										sms
										wechat
									}
								}
								taskSettings {
									enable
									name
									sourceIp
									target
									collect
									alert
									interval
								}
								target
								targetType
								uid
								createTime
								updateTime
								customSubdomains {
									domain
									ip
								}
							}
						}`,
					// #endregion
				});
			},
		},
	},
};
